package modellstadt.geom;


import processing.core.PGraphics;
import processing.core.PMatrix3D;
import processing.core.PVector;


public abstract class AbstractShape extends AbstractGeom {
	public abstract int getNumVertices();

	public abstract void getPosition(int i, float[] coords);

	public abstract void setPosition(int i, float x, float y, float z);

	public abstract void display2D(PGraphics g);

	public abstract void display3D(PGraphics g);

	public Box getBounds() {
		float[] coords = new float[3];
		Box bounds = new Box();
		for (int i = 0; i < getNumVertices(); i++) {
			getPosition(i, coords);
			bounds.addPoint(coords[0], coords[1], coords[2]);
		}
		return bounds;
	}
	public void normaliseSize(float size){
		Box bounds=this.getBounds();
		float sX=bounds.getDimX();
		float sY=bounds.getDimY();
		float sZ=bounds.getDimZ();
		float maxS=sX;
		maxS=Math.max(maxS, sY);
		maxS=Math.max(maxS, sZ);
		scale(size/maxS);
	}
	public void normaliseSize(){
		normaliseSize(1);
	}
	public void transform(PMatrix3D matrix) {
		float[] result = new float[3];
		float[] coordinates = new float[3];
		for (int i = 0; i < getNumVertices(); i++) {
			getPosition(i, coordinates);
			matrix.mult(coordinates, result);
			setPosition(i, result[0], result[1], result[2]);
		}
	}

	public void translate(float x, float y, float z) {
		PMatrix3D matrix = new PMatrix3D();
		matrix.translate(x, y, z);
		transform(matrix);
	}

	public void scale(float scale) {
		scale(scale, scale, scale);
	}

	public void scale(float x, float y, float z) {
		PMatrix3D matrix = new PMatrix3D();
		matrix.scale(x, y, z);
		transform(matrix);
	}

	public void rotateX(float angle) {
		PMatrix3D matrix = new PMatrix3D();
		matrix.rotateX(angle);
		transform(matrix);
	}

	public void rotateY(float angle) {
		PMatrix3D matrix = new PMatrix3D();
		matrix.rotateY(angle);
		transform(matrix);
	}

	public void rotateZ(float angle) {
		PMatrix3D matrix = new PMatrix3D();
		matrix.rotateZ(angle);
		transform(matrix);
	}

	public void XToZ() {
		float[] coords = new float[3];
		for (int i = 0; i < this.getNumVertices(); i++) {
			this.getPosition(i, coords);
			this.setPosition(i, coords[2], coords[1], coords[0]);
		}
	}

	public void YToZ() {
		float[] coords = new float[3];
		for (int i = 0; i < this.getNumVertices(); i++) {
			getPosition(i, coords);
			this.setPosition(i, coords[0], coords[2], coords[1]);
		}
	}

	public void XToY() {
		float[] coords = new float[3];
		for (int i = 0; i < this.getNumVertices(); i++) {
			getPosition(i, coords);
			this.setPosition(i, coords[1], coords[0], coords[2]);
		}
	}

	public PVector getCenter() {
		PVector center = new PVector();
		float[] coords = new float[3];
		for (int i = 0; i < getNumVertices(); i++) {
			getPosition(i, coords);
			center.add(coords[0], coords[1], coords[2]);
		}
		center.div(1f * getNumVertices());
		return center;
	}

	
}
